//
//  Convolutioner_TimeDomain_OpenCL.h
//  FilterModule_Standalone
//
//  Created by kadlubek47 on 06.08.2013.
//  Copyright (c) 2013 kadlubek47. All rights reserved.
//

#ifndef __LowPassFilter_Standalone__Convolutioner_TimeDomain_OpenCL__
#define __LowPassFilter_Standalone__Convolutioner_TimeDomain_OpenCL__


#include "IConvolutioner.h"
#include "ChannelsWindow.h"
#include "OpenCLProcessorBase.h"

class Convolutioner_TimeDomain_OpenCL: public IConvolutioner,  public OpenCLProcessorBase {
public:
    Convolutioner_TimeDomain_OpenCL(Parameters_Convolutioner::ProcessingMethodID processingMethodID, const IRF* irf);
    ~Convolutioner_TimeDomain_OpenCL();
    
    void convolute(AudioBlocks<float_type>& audio);
    void setNewIR(const IRF* irf);
    void setProcessingMethod(Parameters_Convolutioner::ProcessingMethodID& param);
  
private:
    unsigned int blockSize_ = 0;
    unsigned int numOfChannels_ = 0;
    unsigned int irLength_ = 0;
    ChannelsWindowLinear channelsWindowLinear_;
    
    //------------------------------ OpenCL
    //Kernel
    static const char kernelPath_[];
    cl_kernel kernel_convolution_;
    void create_Kernels();
    //.
    
    //Buffers
    bool toSet_BufferGlobalParameters = false;
    
    bool  bufferIn_created_ = false;
    bool bufferOut_created_ = false;
    bool  bufferIR_created_ = false;
    
    unsigned int  bufferIn_length_ = 0;
    unsigned int bufferOut_length_ = 0;
    unsigned int  bufferIR_length_ = 0;
    
    cl_mem bufferIn_;
    cl_mem bufferOut_;
    cl_mem bufferIR_;
    cl_mem bufferGlobalParameters_;
    
    void       recreate_BufferIn ();
    void recreate_BufferOut();
    void recreateAndSet_BufferIRF(const IRF* irf);
    void         create_BufferGlobalParameters();
    void            set_BufferGlobalParameters();
    //.
    
    //Transfering input, output; executing
    void loadBlocksOfChannelsIntoGPU(float* channels);
    void executeKernel();
    void getBlocksOfChannelsFromGPU (float* destiny);
    //.
    //------------------------------ .OpenCL

};

#endif /* defined(__LowPassFilter_Standalone__Convolutioner_TimeDomain_OpenCL__) */
